package com.asiainfo.work.service.master.impl;

import com.asiainfo.work.constant.UserTeamEnum;
import com.asiainfo.work.dao.master.MergeDao;
import com.asiainfo.work.dao.second.ZtBugDao;
import com.asiainfo.work.dao.second.ZtTaskDao;
import com.asiainfo.work.entity.UserGroup;
import com.asiainfo.work.entity.UserMergeCode;
import com.asiainfo.work.request.zentao.BugRequest;
import com.asiainfo.work.service.master.SingleStatisticsService;
import com.asiainfo.work.vo.BugClosedConsumeTimeStatistics;
import com.asiainfo.work.vo.BugClosedStatistics;
import com.asiainfo.work.vo.BugConsumeTimeStatistics;
import com.asiainfo.work.vo.BugStatistics;
import com.asiainfo.work.vo.SingleIndicatorStatistics;
import com.asiainfo.work.vo.TaskActualTimeStatistics;
import com.asiainfo.work.vo.TaskClosedActualTimeStatistics;
import com.asiainfo.work.vo.TaskClosedStatistics;
import com.asiainfo.work.vo.TaskEsTimeStatistics;
import com.asiainfo.work.vo.TaskStatistics;
import com.asiainfo.work.vo.TeamIndicatorStatistics;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author: bf
 * @date: 2021/1/8-10:05
 */
@Service
@Slf4j
public class SingleStatisticsServiceImpl implements SingleStatisticsService {

    @Autowired
    private MergeDao mergeDao ;

    @Autowired
    private ZtTaskDao ztTaskDao ;

    @Autowired
    private ZtBugDao ztBugDao;

    /**
     * 查询单人代码指标
     * @param bugRequest 请求参数
     * @return 返回单人代码指标集合
     */
    @Override
    public List<SingleIndicatorStatistics> singleStatistics(BugRequest bugRequest) {
        log.info("[singleStatistics], 参数: {}" ,new Gson().toJson(bugRequest));
        //1.先查询所有用户
        List<UserGroup> userList = mergeDao.queryUserList();
        Map<String, List<UserGroup>> userListMap = userList.stream()
                .collect(Collectors.groupingBy(UserGroup::getZentaoAccount));

        //2.查询用户当月代码统计量
        List<UserMergeCode> monthlyUserMergeCodes = monthlyMergeCode(bugRequest, userList);
        Map<String, List<UserMergeCode>> monthlyUserMergeCodeMap = monthlyUserMergeCodes.stream()
                .collect(Collectors.groupingBy(UserMergeCode::getAccount));

        //3.查询当月任务总数
        List<TaskStatistics> monthlyTaskStatistics = monthlyTaskCount(bugRequest, userList);
        Map<String, List<TaskStatistics>> monthlyTaskStatisticsMap = monthlyTaskStatistics.stream()
                .collect(Collectors.groupingBy(TaskStatistics::getAccount));

        //4.查询当月任务工期预计总时长
        List<TaskEsTimeStatistics> monthlyTaskEsTimeStatistics = monthlyTaskEsTime(bugRequest, userList);
        Map<String, List<TaskEsTimeStatistics>> monthlyTaskEsTimeStatisticsMap = monthlyTaskEsTimeStatistics.stream()
                .collect(Collectors.groupingBy(TaskEsTimeStatistics::getAccount));

        //5.当月任务完成总数
        List<TaskClosedStatistics> monthlyTaskClosedStatistics = monthlyTaskClosedCount(bugRequest, userList);
        Map<String, List<TaskClosedStatistics>> monthlyTaskClosedStatisticsMap = monthlyTaskClosedStatistics.stream()
                .collect(Collectors.groupingBy(TaskClosedStatistics::getAccount));

        //6.当月已完成的任务消耗实际总时长
        List<TaskClosedActualTimeStatistics> monthlyTaskClosedActualTimeStatistics =
                monthlyTaskClosedActualTime(bugRequest, userList);
        Map<String, List<TaskClosedActualTimeStatistics>> monthlyTaskClosedActualTimeStatisticsMap =
                monthlyTaskClosedActualTimeStatistics.stream().collect(Collectors.groupingBy(TaskClosedActualTimeStatistics::getAccount));

        //7.当月需求开发总工时
        List<TaskActualTimeStatistics> monthlyTaskActualTimeStatistics = monthlyTaskActualTime(bugRequest, userList);
        Map<String, List<TaskActualTimeStatistics>> monthlyTaskActualTimeStatisticsMap =
                monthlyTaskActualTimeStatistics.stream().collect(Collectors.groupingBy(TaskActualTimeStatistics::getAccount));

        //8.当月bug处理总工时
        List<BugConsumeTimeStatistics> monthlyBugConsumeTimeStatistics = monthlyFixBugConsumeTime(bugRequest, userList);
        Map<String, List<BugConsumeTimeStatistics>> monthlyBugConsumeTimeStatisticsMap =
                monthlyBugConsumeTimeStatistics.stream().collect(Collectors.groupingBy(BugConsumeTimeStatistics::getAccount));

        //9.当年合并代码量
        List<UserMergeCode> yearMergeCode = yearMergeCode(bugRequest, userList);
        Map<String, List<UserMergeCode>> yearMergeCodeMap = yearMergeCode.stream()
                .collect(Collectors.groupingBy(UserMergeCode::getAccount));

        //10.当年bug总数
        List<BugStatistics> yearBugCount = yearBugCount(bugRequest, userList);
        Map<String, List<BugStatistics>> yearBugCountMap = yearBugCount.stream()
                .collect(Collectors.groupingBy(BugStatistics::getAccount));

        //11.当年已关闭bug数
        List<BugClosedStatistics> yearBugClosedCount = yearBugClosedCount(bugRequest, userList);
        Map<String, List<BugClosedStatistics>> yearBugClosedCountMap = yearBugClosedCount.stream()
                .collect(Collectors.groupingBy(BugClosedStatistics::getAccount));

        //12.当年修复并且已经关闭bug总时长
        List<BugClosedConsumeTimeStatistics> yearFixBugClosedConsumeTime = yearFixBugClosedConsumeTime(bugRequest, userList);
        Map<String, List<BugClosedConsumeTimeStatistics>> yearFixBugClosedConsumeTimeMap =
                yearFixBugClosedConsumeTime.stream().collect(Collectors.groupingBy(BugClosedConsumeTimeStatistics::getAccount));

        //13. 封装数据
        List<SingleIndicatorStatistics> result = new ArrayList<>();
        //如果accountList为空, 则统计所有的数据, 如不为空,则统计专门的数据
        if(null == bugRequest.getAccount() || bugRequest.getAccount().size() <=0){
            for (UserGroup userGroup:userList) {
                SingleIndicatorStatistics sis = new SingleIndicatorStatistics();
                String account = userGroup.getZentaoAccount();
                //1.封装统计时间
                sis.setStatisticsDate(new Date());

                //2.封装用户账号
                sis.setAccount(userGroup.getZentaoAccount());

                //3.封装用户姓名
                sis.setUserName(userGroup.getUserName());

                //封装团队id
                sis.setTeamId(userGroup.getTeamId());

                //4.封装当月工时  全部按一周22天上班
                sis.setMonthlyWorkTime(22*8);

                //5.封装用户当月代码统计量
                if(monthlyUserMergeCodeMap.containsKey(account)){
                    UserMergeCode userMergeCode = monthlyUserMergeCodeMap.get(account).get(0);
                    sis.setMonthlyMergeCode(userMergeCode.getEffectCount());
                }

                //6.封装当月任务总数
                if(monthlyTaskStatisticsMap.containsKey(account)){
                    TaskStatistics taskStatistics = monthlyTaskStatisticsMap.get(account).get(0);
                    sis.setMonthlyTaskCount(taskStatistics.getTaskCount());
                }

                //7.封装当月任务工期预计总时长
                if(monthlyTaskEsTimeStatisticsMap.containsKey(account)){
                    TaskEsTimeStatistics taskEsTimeStatistics = monthlyTaskEsTimeStatisticsMap.get(account).get(0);
                    sis.setMonthlyTaskEsTime(taskEsTimeStatistics.getTaskTimeCount());
                }

                //8.封装当月任务完成总数
                if(monthlyTaskClosedStatisticsMap.containsKey(account)){
                    TaskClosedStatistics taskClosedStatistics = monthlyTaskClosedStatisticsMap.get(account).get(0);
                    sis.setMonthlyTaskClosedCount(taskClosedStatistics.getTaskClosedCount());
                }

                //9.封装当月已完成的任务实际总时长
                if(monthlyTaskClosedActualTimeStatisticsMap.containsKey(account)){
                    TaskClosedActualTimeStatistics taskClosedActualTimeStatistics = monthlyTaskClosedActualTimeStatisticsMap.get(account).get(0);
                    sis.setMonthlyTaskClosedActualTime(taskClosedActualTimeStatistics.getActualTime());
                }

                //10.封装当月需求开发总工时
                if(monthlyTaskActualTimeStatisticsMap.containsKey(account)){
                    TaskActualTimeStatistics taskActualTimeStatistics = monthlyTaskActualTimeStatisticsMap.get(account).get(0);
                    sis.setMonthlyTaskActualTime(taskActualTimeStatistics.getActualTime());
                }

                //11.封装当月bug处理总工时
                if(monthlyBugConsumeTimeStatisticsMap.containsKey(account)){
                    BugConsumeTimeStatistics bugConsumeTimeStatistics = monthlyBugConsumeTimeStatisticsMap.get(account).get(0);
                    sis.setMonthlyFixBugConsumeTime(bugConsumeTimeStatistics.getConsumeTime());
                }

                //12.封装当年合并代码量
                if(yearMergeCodeMap.containsKey(account)){
                    UserMergeCode userMergeCode = yearMergeCodeMap.get(account).get(0);
                    sis.setYearMergeCode(userMergeCode.getEffectCount());
                }

                //13.封装当年bug总数
                if(yearBugCountMap.containsKey(account)){
                    BugStatistics bugStatistics = yearBugCountMap.get(account).get(0);
                    sis.setYearBugCount(bugStatistics.getBugCount());
                }

                //14.当年已关闭bug数
                if(yearBugClosedCountMap.containsKey(account)){
                    BugClosedStatistics bugClosedStatistics = yearBugClosedCountMap.get(account).get(0);
                    sis.setYearBugClosedCount(bugClosedStatistics.getBugCount());
                }

                //15.封装当年修复并且已经关闭bug总时长
                if(yearFixBugClosedConsumeTimeMap.containsKey(account)){
                    BugClosedConsumeTimeStatistics bugClosedConsumeTimeStatistics = yearFixBugClosedConsumeTimeMap.get(account).get(0);
                    sis.setYearFixBugClosedConsumeTime(bugClosedConsumeTimeStatistics.getConsumeTime());
                }

                //16.封装 bug数/千行（当年bug总数*1000/当年代码量）
                sis.setBugRate("0");
                if(null != sis.getYearBugCount() && null != sis.getYearMergeCode() && 0!= sis.getYearMergeCode()){
                    BigDecimal bugCount_numerator = new BigDecimal(sis.getYearBugCount()).multiply(new BigDecimal(1000));
                    BigDecimal yearMergeCode_denominator = new BigDecimal(sis.getYearMergeCode());
                    String bugRate =bugCount_numerator.divide(yearMergeCode_denominator,4,RoundingMode.HALF_UP).toString();
                    sis.setBugRate(bugRate);
                }

                //17.封装 平均bug解决时长（当年bug修复总时长/当年已关闭bug数）
                sis.setFixBugAvgTime(BigDecimal.ZERO);
                if(null != sis.getYearFixBugClosedConsumeTime() && null != sis.getYearBugClosedCount() && 0 != sis.getYearBugClosedCount()){
                    BigDecimal fixBugAvgTime = sis.getYearFixBugClosedConsumeTime()
                            .divide(new BigDecimal(sis.getYearBugClosedCount()),2,RoundingMode.HALF_UP);
                    sis.setFixBugAvgTime(fixBugAvgTime);
                }

                //18.封装 当月需求任务工时占比（当月需求任务工时/当月总工时）
                sis.setMonthlyTaskTimeRate("0");
                if(null != sis.getMonthlyTaskActualTime() && null != sis.getMonthlyWorkTime() && 0 != sis.getMonthlyWorkTime()){
                    String monthlyTaskTimeRate =sis.getMonthlyTaskActualTime().divide(new BigDecimal(sis.getMonthlyWorkTime()),4,
                                    RoundingMode.HALF_UP).toString();
                    sis.setMonthlyTaskTimeRate(monthlyTaskTimeRate);
                }

                //19.封装 当月bug处理工时占比（当月bug处理总工时/当月总工时）
                sis.setMonthlyBugTimeRate("0");
                if(null != sis.getMonthlyWorkTime() && 0!= sis.getMonthlyWorkTime() && null != sis.getMonthlyFixBugConsumeTime()){
                    String monthlyBugTimeRate =
                            sis.getMonthlyFixBugConsumeTime().divide(new BigDecimal(sis.getMonthlyWorkTime()),4,
                                    RoundingMode.HALF_UP).toString();
                    sis.setMonthlyBugTimeRate(monthlyBugTimeRate);
                }

                //20.封装 平均每任务预计时长（当月任务预计总时长/当月任务数）
                sis.setMonthlyAvgTaskEsTime(BigDecimal.ZERO);
                BigDecimal monthlyAvgTaskEsTime =  null;
                if(null != sis.getMonthlyTaskCount() && 0!= sis.getMonthlyTaskCount() && null != sis.getMonthlyTaskEsTime()){
                    monthlyAvgTaskEsTime =
                            sis.getMonthlyTaskEsTime().divide(new BigDecimal(sis.getMonthlyTaskCount()),2,RoundingMode.HALF_UP);
                    sis.setMonthlyAvgTaskEsTime(monthlyAvgTaskEsTime);
                }

                //21.封装 平均每任务实际时长（当月已完成任务实际总时长/当月已完成任务数）
                BigDecimal monthlyAvgTaskActualTime = null;
                sis.setMonthlyAvgTaskActualTime(BigDecimal.ZERO);
                if(null != sis.getMonthlyTaskClosedCount() && 0 != sis.getMonthlyTaskClosedCount() && null != sis.getMonthlyTaskClosedActualTime()){
                    monthlyAvgTaskActualTime = sis.getMonthlyTaskClosedActualTime()
                            .divide(new BigDecimal(sis.getMonthlyTaskClosedCount()),2,RoundingMode.HALF_UP);
                    sis.setMonthlyAvgTaskActualTime(monthlyAvgTaskActualTime);
                }

                //22.封装 平均每任务时长偏差（平均每任务实际时长-平均每任务预计时长）
                sis.setMonthlyAvgTaskDeviationTime(BigDecimal.ZERO);
                if(null != monthlyAvgTaskActualTime && null != monthlyAvgTaskEsTime){
                    BigDecimal monthlyAvgTaskDeviationTime = monthlyAvgTaskActualTime.subtract(monthlyAvgTaskEsTime);
                    sis.setMonthlyAvgTaskDeviationTime(monthlyAvgTaskDeviationTime);
                }
                result.add(sis);
            }
        }else{
            SingleIndicatorStatistics sis = new SingleIndicatorStatistics();
            //1.封装统计时间
            sis.setStatisticsDate(new Date());

            //2.封装用户账号
            String account = bugRequest.getAccount().get(0);
            String userName = null;
            Integer teamId = null;
            if(userListMap.containsKey(account)){
                userName = userListMap.get(account).get(0).getUserName();
                teamId = userListMap.get(account).get(0).getTeamId();
            }else{
                return null;
            }
            sis.setAccount(account);

            //3.封装用户姓名
            sis.setUserName(userName);

            //封装团队id
            sis.setTeamId(teamId);

            //4.封装当月工时  全部按一周22天上班
            sis.setMonthlyWorkTime(22*8);

            //5.封装用户当月代码统计量
            sis.setMonthlyMergeCode(0);
            if(monthlyUserMergeCodes.size() != 0){
                sis.setMonthlyMergeCode(monthlyUserMergeCodes.get(0).getEffectCount());
            }

            //6.封装当月任务总数
            sis.setMonthlyTaskCount(0);
            if(monthlyTaskStatistics.size() != 0){
                sis.setMonthlyTaskCount(monthlyTaskStatistics.get(0).getTaskCount());
            }

            //7.封装当月任务工期预计总时长
            sis.setMonthlyTaskEsTime(BigDecimal.ZERO);
            if(monthlyTaskEsTimeStatistics.size() != 0){
                sis.setMonthlyTaskEsTime(monthlyTaskEsTimeStatistics.get(0).getTaskTimeCount());
            }

            //8.封装当月任务完成总数
            sis.setMonthlyTaskClosedCount(0);
            if(monthlyTaskClosedStatistics.size() != 0){
                sis.setMonthlyTaskClosedCount(monthlyTaskClosedStatistics.get(0).getTaskClosedCount());
            }

            //9.封装当月已完成的任务实际总时长
            sis.setMonthlyTaskClosedActualTime(BigDecimal.ZERO);
            if(monthlyTaskClosedActualTimeStatistics.size() != 0){
                sis.setMonthlyTaskClosedActualTime(monthlyTaskClosedActualTimeStatistics.get(0).getActualTime());
            }

            //10.封装当月需求开发总工时
            sis.setMonthlyTaskActualTime(BigDecimal.ZERO);
            if(monthlyTaskActualTimeStatistics.size() != 0){
                sis.setMonthlyTaskActualTime(monthlyTaskActualTimeStatistics.get(0).getActualTime());
            }

            //11.封装当月bug处理总工时
            sis.setMonthlyFixBugConsumeTime(BigDecimal.ZERO);
            if(monthlyBugConsumeTimeStatistics.size() != 0){
                sis.setMonthlyFixBugConsumeTime(monthlyBugConsumeTimeStatistics.get(0).getConsumeTime());
            }

            //12.封装当年合并代码量
            sis.setYearMergeCode(0);
            if(yearMergeCode.size() != 0){
                sis.setYearMergeCode(yearMergeCode.get(0).getEffectCount());
            }

            //13.封装当年bug总数
            sis.setYearBugCount(0);
            if(yearBugCount.size() != 0){
                sis.setYearBugCount(yearBugCount.get(0).getBugCount());
            }

            //14.当年已关闭bug数
            sis.setYearBugClosedCount(0);
            if(yearBugClosedCount.size() != 0){
                sis.setYearBugClosedCount(yearBugClosedCount.get(0).getBugCount());
            }

            //15.封装当年修复并且已经关闭bug总时长
            sis.setYearFixBugClosedConsumeTime(BigDecimal.ZERO);
            if(yearFixBugClosedConsumeTime.size() != 0){
                sis.setYearFixBugClosedConsumeTime(yearFixBugClosedConsumeTime.get(0).getConsumeTime());
            }

            //16封装bug率
            sis.setBugRate("0");
            if(null != sis.getYearBugCount() && null != sis.getYearMergeCode() && 0!= sis.getYearMergeCode()){
                BigDecimal bugCount_numerator = new BigDecimal(sis.getYearBugCount()).multiply(new BigDecimal(1000));
                BigDecimal yearMergeCode_denominator = new BigDecimal(sis.getYearMergeCode());
                String bugRate = bugCount_numerator.divide(yearMergeCode_denominator,4,RoundingMode.HALF_UP).toString();
                sis.setBugRate(bugRate);
            }

            //17.封装 平均bug解决时长（当年bug修复总时长/当年已关闭bug数）
            sis.setFixBugAvgTime(BigDecimal.ZERO);
            if(null != sis.getYearFixBugClosedConsumeTime() && null != sis.getYearBugClosedCount() && 0 != sis.getYearBugClosedCount()){
                BigDecimal fixBugAvgTime = sis.getYearFixBugClosedConsumeTime()
                        .divide(new BigDecimal(sis.getYearBugClosedCount()),2,RoundingMode.HALF_UP);
                sis.setFixBugAvgTime(fixBugAvgTime);
            }

            //18.封装 当月需求任务工时占比（当月需求任务工时/当月总工时）
            sis.setMonthlyTaskTimeRate("0");
            if(null != sis.getMonthlyTaskActualTime() && null != sis.getMonthlyWorkTime() && 0 != sis.getMonthlyWorkTime()){
                String monthlyTaskTimeRate =
                        sis.getMonthlyTaskActualTime().divide(new BigDecimal(sis.getMonthlyWorkTime()),4,
                                RoundingMode.HALF_UP).toString();
                sis.setMonthlyTaskTimeRate(monthlyTaskTimeRate);
            }

            //19.封装 当月bug处理工时占比（当月bug处理总工时/当月总工时）
            sis.setMonthlyBugTimeRate("0");
            if(null != sis.getMonthlyWorkTime() && 0!= sis.getMonthlyWorkTime() && null != sis.getMonthlyFixBugConsumeTime()){
                String monthlyBugTimeRate =sis.getMonthlyFixBugConsumeTime().divide(new BigDecimal(sis.getMonthlyWorkTime()),4,
                                RoundingMode.HALF_UP).toString();
                sis.setMonthlyBugTimeRate(monthlyBugTimeRate);
            }

            //20.封装 平均每任务预计时长（当月任务预计总时长/当月任务数）
            sis.setMonthlyAvgTaskEsTime(BigDecimal.ZERO);
            BigDecimal monthlyAvgTaskEsTime =  null;
            if(null != sis.getMonthlyTaskCount() && 0!= sis.getMonthlyTaskCount() && null != sis.getMonthlyTaskEsTime()){
                monthlyAvgTaskEsTime = sis.getMonthlyTaskEsTime().divide(new BigDecimal(sis.getMonthlyTaskCount()),2, RoundingMode.HALF_UP);
                sis.setMonthlyAvgTaskEsTime(monthlyAvgTaskEsTime);
            }

            //21.封装 平均每任务实际时长（当月已完成任务实际总时长/当月已完成任务数）
            BigDecimal monthlyAvgTaskActualTime = null;
            sis.setMonthlyAvgTaskActualTime(BigDecimal.ZERO);
            if(null != sis.getMonthlyTaskClosedCount() && 0 != sis.getMonthlyTaskClosedCount() && null != sis.getMonthlyTaskClosedActualTime()){
                monthlyAvgTaskActualTime = sis.getMonthlyTaskClosedActualTime()
                        .divide(new BigDecimal(sis.getMonthlyTaskClosedCount()),2,RoundingMode.HALF_UP);
                sis.setMonthlyAvgTaskActualTime(monthlyAvgTaskActualTime);
            }

            //22.封装 平均每任务时长偏差（平均每任务实际时长-平均每任务预计时长）
            sis.setMonthlyAvgTaskDeviationTime(BigDecimal.ZERO);
            if(null != monthlyAvgTaskActualTime && null != monthlyAvgTaskEsTime){
                BigDecimal monthlyAvgTaskDeviationTime = monthlyAvgTaskActualTime.subtract(monthlyAvgTaskEsTime);
                sis.setMonthlyAvgTaskDeviationTime(monthlyAvgTaskDeviationTime);
            }
            result.add(sis);
        }
        return formatterResult(result);
    }

    /**
     * 返回结果格式化. 将数据做判空处理, 将比例计算成 %单位
     * @param lists
     * @return
     */
    public List<SingleIndicatorStatistics> formatterResult (List<SingleIndicatorStatistics> lists){
        List<SingleIndicatorStatistics> result = new ArrayList<>();
        for(SingleIndicatorStatistics  sis : lists){
            if(null == sis.getMonthlyMergeCode()){
                sis.setMonthlyMergeCode(0);
            }
            if(null == sis.getMonthlyTaskCount()){
                sis.setMonthlyTaskCount(0);
            }
            if(null == sis.getMonthlyTaskEsTime()){
                sis.setMonthlyTaskEsTime(BigDecimal.ZERO);
            }
            if(null == sis.getMonthlyTaskClosedCount()){
                sis.setMonthlyTaskClosedCount(0);
            }
            if(null == sis.getMonthlyTaskClosedActualTime()){
                sis.setMonthlyTaskClosedActualTime(BigDecimal.ZERO);
            }else{
                BigDecimal monthlyTaskClosedActualTime = sis.getMonthlyTaskClosedActualTime().setScale(1,BigDecimal.ROUND_HALF_UP);
                sis.setMonthlyTaskClosedActualTime(monthlyTaskClosedActualTime);
            }
            if(null == sis.getMonthlyTaskActualTime()){
                sis.setMonthlyTaskActualTime(BigDecimal.ZERO);
            }else{
                BigDecimal monthlyTaskActualTime = sis.getMonthlyTaskActualTime().setScale(1, BigDecimal.ROUND_HALF_UP);
                sis.setMonthlyTaskActualTime(monthlyTaskActualTime);
            }

            if(null == sis.getMonthlyFixBugConsumeTime()){
                sis.setMonthlyFixBugConsumeTime(BigDecimal.ZERO);
            }
            if(null == sis.getYearMergeCode()){
                sis.setYearMergeCode(0);
            }
            if(null == sis.getYearBugCount()){
                sis.setYearBugCount(0);
            }
            if(null == sis.getYearBugClosedCount()){
                sis.setYearBugClosedCount(0);
            }
            if(null == sis.getYearFixBugClosedConsumeTime()){
                sis.setYearFixBugClosedConsumeTime(BigDecimal.ZERO);
            }else{
                BigDecimal yearFixBugClosedConsumeTime = sis.getYearFixBugClosedConsumeTime().setScale(1,BigDecimal.ROUND_HALF_UP);
                sis.setYearFixBugClosedConsumeTime(yearFixBugClosedConsumeTime);
            }

            if(null == sis.getBugRate() || "0".equals(sis.getBugRate())){
                sis.setBugRate("0");
            }else{
                String bugRate = new BigDecimal(sis.getBugRate()).multiply(new BigDecimal("100")).setScale(2,
                        BigDecimal.ROUND_HALF_UP).toString() +"%";
                sis.setBugRate(bugRate);
            }

            if(null == sis.getMonthlyTaskTimeRate() || "0".equals(sis.getMonthlyTaskTimeRate())){
                sis.setMonthlyTaskTimeRate("0");
            }else{
                String monthlyTaskTimeRate = new BigDecimal(sis.getMonthlyTaskTimeRate()).multiply(new BigDecimal("100")).setScale(2,
                        BigDecimal.ROUND_HALF_UP).toString() +"%";
                sis.setMonthlyTaskTimeRate(monthlyTaskTimeRate);
            }

            if(null == sis.getMonthlyBugTimeRate() || "0".equals(sis.getMonthlyBugTimeRate())){
                sis.setMonthlyBugTimeRate("0");
            }else{
                String monthlyBugTimeRate = new BigDecimal(sis.getMonthlyBugTimeRate()).multiply(new BigDecimal("100")).setScale(2,
                        BigDecimal.ROUND_HALF_UP).toString() +"%";
                sis.setMonthlyBugTimeRate(monthlyBugTimeRate);
            }
            result.add(sis);
        }
        return  result;
    }

    /**
     * 查询当月代码合并量,如果account为空则查询 指定userList的代码合并量
     * @param bugRequest 查询条件
     * @param userList 指定用户
     * @return 用户的代码合并量集合
     */
    public List<UserMergeCode> monthlyMergeCode(BugRequest bugRequest, List<UserGroup> userList){
        log.info("查询月度代码合并量, 参数bugRequest={} userList={} ", new Gson().toJson(bugRequest), new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList = bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<UserMergeCode> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String endTime = bugRequest.getEndTime();
        String startTime = bugRequest.getStartTime();
        return mergeDao.query(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当月任务数
     * @param bugRequest 请求参数
     * @return 用户当月任务数集合
     */
    public List<TaskStatistics> monthlyTaskCount(BugRequest bugRequest, List<UserGroup> userList){
        log.info("[monthlyTaskCount] ,参数 bugRequest={} , userList={}", new Gson().toJson(bugRequest), new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList = bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<TaskStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String endTime = bugRequest.getEndTime();
        String startTime = bugRequest.getStartTime();
        return ztTaskDao.queryTask(startTime, endTime, accountList, plusPage);
    }

    /**
     * 当月任务预计总工时
     * @param bugRequest 请求参数
     * @return 用户当月任务预计总工时列表
     */
    private List<TaskEsTimeStatistics> monthlyTaskEsTime(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[monthlyTaskEsTime] ,参数 bugRequest={}, userList={}", new Gson().toJson(bugRequest), new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList = bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<TaskEsTimeStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String endTime = bugRequest.getEndTime();
        String startTime = bugRequest.getStartTime();
        return ztTaskDao.queryTaskEsTime(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当月已经关闭任务数
     * @param bugRequest 请求参数
     * @return 当月任务预计总工时列表
     */
    private List<TaskClosedStatistics> monthlyTaskClosedCount(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[monthlyTaskClosedCount] ,参数 bugRequest={},userList={}", new Gson().toJson(bugRequest),
                new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList = bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<TaskClosedStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String endTime = bugRequest.getEndTime();
        String startTime = bugRequest.getStartTime();
        return ztTaskDao.queryTaskClosed(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当月已经完成任务的实际工时
     * @param bugRequest 请求参数
     * @return 用户当月已经完成任务的实际工时列表
     */
    private List<TaskClosedActualTimeStatistics> monthlyTaskClosedActualTime(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[monthlyTaskClosedActualTime] ,参数 bugRequest={},userList={}", new Gson().toJson(bugRequest),
                new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList = bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<TaskClosedActualTimeStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String endTime = bugRequest.getEndTime();
        String startTime = bugRequest.getStartTime();
        return ztTaskDao.queryTaskClosedActualTime(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当月实际开发工时
     * @param bugRequest 请求参数
     * @return 用户当月实际开发工时列表
     */
    private List<TaskActualTimeStatistics> monthlyTaskActualTime(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[monthlyTaskActualTime] ,参数 bugRequest={},userList={}", new Gson().toJson(bugRequest),
                new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList = bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<TaskActualTimeStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String endTime = bugRequest.getEndTime();
        String startTime = bugRequest.getStartTime();
        return ztTaskDao.queryTaskActualTime(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当月bug处理总工时
     * @param bugRequest 请求参数
     * @return用户当月bug处理总工时列表
     */
    private List<BugConsumeTimeStatistics> monthlyFixBugConsumeTime(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[monthlyFixBugConsumeTime] ,参数 bugRequest={},userList={}", new Gson().toJson(bugRequest),
                new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList = bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<BugConsumeTimeStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String endTime = bugRequest.getEndTime();
        String startTime = bugRequest.getStartTime();
        return ztBugDao.queryConsumeBugTime(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当年代码合并量
     * @param bugRequest 请求参数
     * @return用户当年bug处理总工时列表
     */
    private List<UserMergeCode> yearMergeCode(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("查询月度代码合并量, 参数bugRequest={} userList={} ", new Gson().toJson(bugRequest), new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList =  bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<UserMergeCode> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String year = bugRequest.getEndTime().split("-")[0];
        String endTime = year + "-12-31 23:59:59";
        String startTime = year + "-01-01 00:00:00";
        return mergeDao.query(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当年bug数
     * @param bugRequest 请求参数
     * @return 用户当年bug数列表
     */
    private List<BugStatistics> yearBugCount(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[yearBugCount] ,参数 bugRequest={},userList={}", new Gson().toJson(bugRequest),
                new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList =  bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<BugStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String year = bugRequest.getEndTime().split("-")[0];
        String endTime = year + "-12-31 23:59:59";
        String startTime = year + "-01-01 00:00:00";
        return ztBugDao.queryBugCount(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当年bug关闭数
     * @param bugRequest 请求参数
     * @return 用户当年bug关闭数列表
     */
    private List<BugClosedStatistics> yearBugClosedCount(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[yearBugCount] ,参数 bugRequest={},userList={}", new Gson().toJson(bugRequest),
                new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList =  bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<BugClosedStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String year = bugRequest.getEndTime().split("-")[0];
        String endTime = year + "-12-31 23:59:59";
        String startTime = year + "-01-01 00:00:00";
        return ztBugDao.queryBugClosedCount(startTime, endTime, accountList, plusPage);
    }

    /**
     * 统计用户当年修复并且已经关闭的bug消耗时间
     * @param bugRequest 请求参数
     * @return 修复并且已经关闭的bug消耗时间列表
     */
    private List<BugClosedConsumeTimeStatistics> yearFixBugClosedConsumeTime(BugRequest bugRequest, List<UserGroup> userList) {
        log.info("[yearFixBugClosedConsumeTime] ,参数 bugRequest={},userList={}", new Gson().toJson(bugRequest),
                new Gson().toJson(userList));
        //查询当月代码量(如果没有没有传入account, 则查询userList中的用户信息)
        List<String> accountList =  bugRequest.getAccount();
        if(null == accountList ||accountList.size() <=0){
            accountList = userList.stream().map(UserGroup::getZentaoAccount).collect(Collectors.toList());
        }
        IPage<BugClosedConsumeTimeStatistics> plusPage = new Page<>(bugRequest.getPage(),
                bugRequest.getSize());
        String year = bugRequest.getEndTime().split("-")[0];
        String endTime = year + "-12-31 23:59:59";
        String startTime = year + "-01-01 00:00:00";
        return ztBugDao.queryClosedBugConsumeTime(startTime, endTime, accountList, plusPage);
    }

    /**
     * 查询团队代码指标
     * 1.先后获取所有人的指标信息
     * 2.按团队id分组, 获取分组后的map
     * 3.遍历每个 map, 累加map中所有的列
     * 4.组装返回数据
     * @param bugRequest 请求参数
     * @return 返回团队代码指标集合
     */
    @Override
    public List<TeamIndicatorStatistics> teamStatistics(BugRequest bugRequest) {
        log.info("[teamStatistics], 参数 bugRequest={}", new Gson().toJson(bugRequest));
        //1.查询团队成员指标信息, 按团队id分类
        List<SingleIndicatorStatistics> singleIndicatorStatistics = singleStatistics(bugRequest);
        Map<Integer, List<SingleIndicatorStatistics>> singleIndicatorMap = singleIndicatorStatistics.stream()
                .collect(Collectors.groupingBy(SingleIndicatorStatistics::getTeamId));
        List<TeamIndicatorStatistics> teamList = new ArrayList<>();
        //2.统计每个团队, 将单项数据累加
        singleIndicatorMap.forEach((k,v)->{
            TeamIndicatorStatistics teamIndicatorStatistics = teamStatisticsData(v);
            teamList.add(teamIndicatorStatistics);
        });
        return teamList;
    }

    /**
     * 统计每个团队指标数据
     * @param v 团队中每个人的指标统计
     * @return 团队的指标统计
     */
    private TeamIndicatorStatistics teamStatisticsData(List<SingleIndicatorStatistics> v) {
        Date statisticsDate = null;
        Integer teamId = null;
        Integer monthlyWorkTime = 0;
        Integer monthlyMergeCode = 0;
        Integer monthlyTaskCount = 0;
        BigDecimal monthlyTaskEsTime = new BigDecimal("0");
        Integer monthlyTaskClosedCount = 0;
        BigDecimal monthlyTaskClosedActualTime = new BigDecimal("0");
        BigDecimal monthlyTaskActualTime = new BigDecimal("0");
        BigDecimal monthlyFixBugConsumeTime = new BigDecimal("0");
        Integer yearMergeCode = 0;
        Integer yearBugCount = 0;
        Integer yearBugClosedCount = 0;
        BigDecimal yearFixBugClosedConsumeTime = new BigDecimal("0");

        for(SingleIndicatorStatistics sis : v){
            statisticsDate = sis.getStatisticsDate();
            teamId = sis.getTeamId();
            monthlyWorkTime += sis.getMonthlyWorkTime();
            if(null != sis.getMonthlyMergeCode()){
                monthlyMergeCode += sis.getMonthlyMergeCode();
            }
            if(null != sis.getMonthlyTaskCount()){
                monthlyTaskCount += sis.getMonthlyTaskCount();
            }
            if(null != sis.getMonthlyTaskEsTime()){
                monthlyTaskEsTime =  monthlyTaskEsTime.add(sis.getMonthlyTaskEsTime());
            }
            if(null != sis.getMonthlyTaskClosedCount()){
                monthlyTaskClosedCount += sis.getMonthlyTaskClosedCount();
            }
            if(null != sis.getMonthlyTaskClosedActualTime()){
                monthlyTaskClosedActualTime = monthlyTaskClosedActualTime.add(sis.getMonthlyTaskClosedActualTime());
            }
            if(null != sis.getMonthlyTaskActualTime()){
                monthlyTaskActualTime = monthlyTaskActualTime.add(sis.getMonthlyTaskActualTime());
            }
            if(null != sis.getMonthlyFixBugConsumeTime()){
                monthlyFixBugConsumeTime = monthlyFixBugConsumeTime.add(sis.getMonthlyFixBugConsumeTime());
            }
            if(null != sis.getYearMergeCode()){
                yearMergeCode += sis.getYearMergeCode();
            }
            if(null != sis.getYearBugCount()){
                yearBugCount += sis.getYearBugCount();
            }
            if(null!= sis.getYearBugClosedCount()){
                yearBugClosedCount += sis.getYearBugClosedCount();
            }
            if(null != sis.getYearFixBugClosedConsumeTime()){
                yearFixBugClosedConsumeTime = yearFixBugClosedConsumeTime.add(sis.getYearFixBugClosedConsumeTime());
            }
        }

        //封装团队指标信息
        TeamIndicatorStatistics tis = new TeamIndicatorStatistics();
        tis.setStatisticsDate(statisticsDate);
        tis.setTeamId(teamId);
        tis.setTeamName(UserTeamEnum.getTeamValue(teamId));
        if(null == monthlyWorkTime){
            monthlyWorkTime = 0;
        }
        tis.setMonthlyWorkTime(monthlyWorkTime);

        if(null == monthlyMergeCode){
            monthlyMergeCode = 0;
        }
        tis.setMonthlyMergeCode(monthlyMergeCode);

        if(null == monthlyTaskCount){
            monthlyTaskCount= 0;
        }
        tis.setMonthlyTaskCount(monthlyTaskCount);

        if(null == monthlyTaskEsTime){
            monthlyTaskEsTime = BigDecimal.ZERO;
        }
        tis.setMonthlyTaskEsTime(monthlyTaskEsTime);

        if(null == monthlyTaskClosedCount){
            monthlyTaskClosedCount = 0;
        }
        tis.setMonthlyTaskClosedCount(monthlyTaskClosedCount);

        if(null == monthlyTaskClosedActualTime){
            tis.setMonthlyTaskClosedActualTime(BigDecimal.ZERO);
        }else{
            tis.setMonthlyTaskClosedActualTime(monthlyTaskClosedActualTime.setScale(1,BigDecimal.ROUND_HALF_UP));
        }

        if(null == monthlyTaskActualTime){
            tis.setMonthlyTaskActualTime(BigDecimal.ZERO);
        }else{
            tis.setMonthlyTaskActualTime(monthlyTaskActualTime.setScale(1,BigDecimal.ROUND_HALF_UP));
        }

        if(null == monthlyFixBugConsumeTime){
            monthlyFixBugConsumeTime = BigDecimal.ZERO;
        }
        tis.setMonthlyFixBugConsumeTime(monthlyFixBugConsumeTime);

        if(null == yearMergeCode){
            yearMergeCode = 0;
        }
        tis.setYearMergeCode(yearMergeCode);

        if(null == yearBugCount){
            yearBugCount = 0;
        }
        tis.setYearBugCount(yearBugCount);

        if(null == yearBugClosedCount){
            yearBugClosedCount = 0;
        }
        tis.setYearBugClosedCount(yearBugClosedCount);

        if(null == yearFixBugClosedConsumeTime){
            yearFixBugClosedConsumeTime = BigDecimal.ZERO;
        }else{
            tis.setYearFixBugClosedConsumeTime(yearFixBugClosedConsumeTime.setScale(1,BigDecimal.ROUND_HALF_UP));
        }

        String bugRate = "0";
        tis.setBugRate(bugRate);
        if(0 != yearBugCount && 0!= yearMergeCode){
            BigDecimal bugCount_numerator = new BigDecimal(yearBugCount).multiply(new BigDecimal(1000));
            BigDecimal yearMergeCode_denominator = new BigDecimal(yearMergeCode);
            bugRate = bugCount_numerator.divide(yearMergeCode_denominator,4,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2,
                    BigDecimal.ROUND_HALF_UP).toString() +"%";
            tis.setBugRate(bugRate);
        }

        tis.setFixBugAvgTime(BigDecimal.ZERO);
        if(null != tis.getYearFixBugClosedConsumeTime() && null != tis.getYearBugClosedCount() && 0 != tis.getYearBugClosedCount()){
            BigDecimal fixBugAvgTime = tis.getYearFixBugClosedConsumeTime()
                    .divide(new BigDecimal(tis.getYearBugClosedCount()),2,RoundingMode.HALF_UP);
            tis.setFixBugAvgTime(fixBugAvgTime);
        }

        tis.setMonthlyTaskTimeRate("0");
        if(null != tis.getMonthlyTaskCount() && null != tis.getMonthlyWorkTime() && 0 != tis.getMonthlyWorkTime()){
            String monthlyTaskTimeRate =
                    tis.getMonthlyTaskActualTime().divide(new BigDecimal(tis.getMonthlyWorkTime()),4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2,
                            BigDecimal.ROUND_HALF_UP).toString() +"%";
            tis.setMonthlyTaskTimeRate(monthlyTaskTimeRate);
        }

        tis.setMonthlyBugTimeRate("0");
        if(null != tis.getMonthlyWorkTime() && 0!= tis.getMonthlyWorkTime() && null != tis.getMonthlyFixBugConsumeTime() && !BigDecimal.ZERO.equals(tis.getMonthlyFixBugConsumeTime())){
            String monthlyBugTimeRate =
                    tis.getMonthlyFixBugConsumeTime().divide(new BigDecimal(tis.getMonthlyWorkTime()),4,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2,
                            BigDecimal.ROUND_HALF_UP).toString() +"%";
            tis.setMonthlyBugTimeRate(monthlyBugTimeRate);
        }

        tis.setMonthlyAvgTaskEsTime(BigDecimal.ZERO);
        BigDecimal monthlyAvgTaskEsTime =  null;
        if(null != tis.getMonthlyTaskCount() && 0!= tis.getMonthlyTaskCount() && null != tis.getMonthlyTaskEsTime()){
            monthlyAvgTaskEsTime =
                    tis.getMonthlyTaskEsTime().divide(new BigDecimal(tis.getMonthlyTaskCount()),2,RoundingMode.HALF_UP);
            tis.setMonthlyAvgTaskEsTime(monthlyAvgTaskEsTime);
        }

        BigDecimal monthlyAvgTaskActualTime = null;
        tis.setMonthlyAvgTaskActualTime(BigDecimal.ZERO);
        if(null != tis.getMonthlyTaskClosedCount() && 0 != tis.getMonthlyTaskClosedCount() && null != tis.getMonthlyTaskClosedActualTime()){
            monthlyAvgTaskActualTime = tis.getMonthlyTaskClosedActualTime()
                    .divide(new BigDecimal(tis.getMonthlyTaskClosedCount()),2,RoundingMode.HALF_UP);
            tis.setMonthlyAvgTaskActualTime(monthlyAvgTaskActualTime);
        }

        tis.setMonthlyAvgTaskDeviationTime(BigDecimal.ZERO);
        if(null != monthlyAvgTaskActualTime && null != monthlyAvgTaskEsTime){
            BigDecimal monthlyAvgTaskDeviationTime = monthlyAvgTaskActualTime.subtract(monthlyAvgTaskEsTime);
            tis.setMonthlyAvgTaskDeviationTime(monthlyAvgTaskDeviationTime);
        }
        return tis;
    }

}
